﻿using System.Linq.PageList;
using Dyao.Repository.Abstractions;
using Dyao.Book.Application.Abstractions;
using Dyao.Book.BusApplication;
using Dyao.Book.Contract;
using Dyao.Book.Entity;
using Foundation.Core;
using Foundation.Service.Bus.Core;
using Foundation.Uow;

namespace Dyao.Book.Application
{
    /// <summary>
    /// 任务中心配置
    /// </summary>
    public class TaskCenterSettingsApplication : BaseApplication, ITaskCenterSettingsApplication
    {
        //任务中心配置仓储
        private readonly ITaskCenterSettingsRepository _taskCenterSettingsRepository;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="taskCenterSettingsRepository">任务中心配置仓储</param>
        public TaskCenterSettingsApplication(ITaskCenterSettingsRepository taskCenterSettingsRepository)
        {
            _taskCenterSettingsRepository = taskCenterSettingsRepository;
        }

        /// <summary>
        /// 分页获取任务中心配置信息
        /// </summary>
        /// <param name="pageFilter">分页筛选器</param>
        /// <param name="cancellationToken">取消操作的通知</param>
        /// <returns>返回任务中心配置</returns>
        public async Task<IPageList<TaskCenterSettingsDto>> GetPageListAsync(IPageFilter<TaskCenterSettingFilterDto> pageFilter, CancellationToken cancellationToken = default)
        {
            var result = new PageList<TaskCenterSettingsDto>();
            using var unitOfWork = UnitOfWorkManager.Begin(isReadDb: true);
            var pageList = await _taskCenterSettingsRepository.GetPageListAsync(pageFilter, cancellationToken);

            if (pageList.Records == 0) return result;

            var resultList = ObjectMapper.Map<List<TaskCenterSettingsEntity>, List<TaskCenterSettingsDto>>(pageList.Data);

            return (PageList<TaskCenterSettingsDto>)pageList.ToMap(resultList);
        }


        /// <summary>
        /// 新增任务中心配置信息
        /// </summary>
        /// <param name="settingModel">配置信息</param>
        /// <param name="cancellationToken">取消操作的通知</param>
        /// <returns></returns>
        public async Task CreateTaskCenterSettingAsync(TaskCenterSettingsDto settingModel, CancellationToken cancellationToken = default)
        {
            #region 数据校验

            CheckSettings(settingModel);

            #endregion

            using (var unitOfWork = UnitOfWorkManager.Begin())
            {
                TaskCenterSettingsEntity entityModel = await _taskCenterSettingsRepository.FindAsync(s => s.ID == settingModel.Id, cancellationToken: cancellationToken);
                if (entityModel != null)
                {
                    throw new BusinessException("taskcenter_Setting_KeyIsExists", "任务的Key已存在，请重新定义！");
                }

                entityModel = ObjectMapper.Map<TaskCenterSettingsDto, TaskCenterSettingsEntity>(settingModel);
                await _taskCenterSettingsRepository.InsertAsync(entityModel, cancellationToken: cancellationToken);
                await unitOfWork.CompleteAsync(cancellationToken);
            }
        }

        /// <summary>
        /// 修改任务中心配置信息
        /// </summary>
        /// <param name="settingModel">配置信息</param>
        /// <param name="cancellationToken">取消操作的通知</param>
        /// <returns></returns>
        public async Task ModifiedTaskCenterSettingAsync(TaskCenterSettingsDto settingModel, CancellationToken cancellationToken = default)
        {
            #region 数据校验

            CheckSettings(settingModel);

            #endregion

            using (var unitOfWork = UnitOfWorkManager.Begin())
            {
                TaskCenterSettingsEntity entityModel = await _taskCenterSettingsRepository.FindAsync(s => s.ID == settingModel.Id, cancellationToken: cancellationToken);
                if (entityModel == null)
                {
                    throw new BusinessException("taskcenter_Setting_KeyNotFound", "任务的Key不已存在！");
                }

                entityModel = ObjectMapper.Map<TaskCenterSettingsDto, TaskCenterSettingsEntity>(settingModel, entityModel);
                await unitOfWork.CompleteAsync(cancellationToken);
            }
        }

        /// <summary>
        /// 获取任务中心配置信息
        /// </summary>
        /// <param name="settingId">配置信息ID</param>
        /// <param name="cancellationToken">取消操作的通知</param>
        /// <returns>返回配置信息</returns>
        public async Task<TaskCenterSettingsDto> GetTaskCenterSettingAsync(string settingId, CancellationToken cancellationToken = default)
        {
            TaskCenterSettingsDto settingModel = null;
            using (var unitOfWork = UnitOfWorkManager.Begin())
            {
                var settingEntity = await _taskCenterSettingsRepository.FindAsync(s => s.ID == settingId, cancellationToken: cancellationToken);

                if (settingEntity != null)
                {
                    settingModel = ObjectMapper.Map<TaskCenterSettingsEntity, TaskCenterSettingsDto>(settingEntity);
                }
            }

            return settingModel;
        }

        /// <summary>
        /// 删除任务配置中心配置信息
        /// </summary>
        /// <param name="settingIds">配置主键集合</param>
        /// <param name="cancellationToken">取消操作的通知</param>
        /// <returns></returns>
        public async Task DeleteTaskCenterSettingAsync(List<string> settingIds, CancellationToken cancellationToken)
        {
            using (var unitOfWork = UnitOfWorkManager.Begin())
            {
                if (settingIds.IsNullOrEmpty()) return;

                await settingIds.PagingProcessAsync(async pageIdList =>
                {

                    await _taskCenterSettingsRepository.DeleteAsync(s => pageIdList.ToList().Contains(s.ID), cancellationToken: cancellationToken);
                    await unitOfWork.SaveChangesAsync(cancellationToken);
                }, 100);

                await unitOfWork.CompleteAsync(cancellationToken);
            }
        }

        /// <summary>
        /// 获取尚未配置的TaskCode信息
        /// </summary>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public async Task<List<TaskCenterCodeDto>> GetUnSettingTaskCodesAsync(CancellationToken cancellationToken = default)
        {
            List<TaskCenterSettingsEntity> settings;
            using (var unitOfWork = UnitOfWorkManager.Begin())
            {
                settings = await _taskCenterSettingsRepository.GetListAsync(cancellationToken);
            }

            var list = TaskCenterCodeManager.GetAllCodes().Where(m => !settings.Any(s => s.ID == m.TaskCode)).ToList();

            return list;
        }

        protected void CheckSettings(TaskCenterSettingsDto settingModel)
        {
            if (string.IsNullOrEmpty(settingModel.Id))
            {
                throw new BusinessException("taskcenter_Setting_KeyIsEmpty", "TaskCode不能为空！");
            }

            if (!TaskCenterCodeManager.IsExists(settingModel.Id))
            {
                throw new BusinessException("taskcenter_Setting_KeyIsInvalid", "找不到TaskCode！");
            }

            if (string.IsNullOrEmpty(settingModel.DisplayName))
            {
                throw new BusinessException("taskcenter_Setting_DisplayIsEmpty", "任务名称不能为空！");
            }

            if (string.IsNullOrEmpty(settingModel.CommandName))
            {
                throw new BusinessException("taskcenter_Setting_CommandIsEmpty", "任务命令不能为空！");
            }

            var typeFinder = GetService<ITypeFinder>();

            Type type = typeFinder.GetByFullName(settingModel.CommandName);

            if (type == null) throw new BusinessException("taskcenter_setting_commandNotfound", "Command名称找不到对应类型");

            if (!typeof(ICommand).IsAssignableFrom(type) || !typeof(ITaskCenterCommand).IsAssignableFrom(type))
            {
                throw new BusinessException("taskcenter_setting_commandInvalid", $"Command必须实现{nameof(ICommand)}和{nameof(ITaskCenterCommand)}接口。");
            }
        }

    }
}
